package com.ply.utils;

import com.ply.utils.encoding.Base64;
import org.apache.commons.codec.binary.Hex;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ply.entity.vo.Token;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author XiaoPan
 * date: 2022/1/8 11:43
 * <p>
 * action: 关于Token的一些方法
 */
public class TokenUtils {
    private static Logger log = LogManager.getLogger(TokenUtils.class.getName());



    //设置过期时间
    private static final long EXPIRE_DATE = 600 * 60 * 1000;

    public static void main(String[] args) {
        String s = toToken(1, "用户");
        Map<String, Object> tokenAll = getTokenAll(s);
        System.out.println(s);
        int id = (int) tokenAll.get("id");
        String type = (String) tokenAll.get("type");
        long expireTime = (long) tokenAll.get("expireTime");
        String  md5 = (String) tokenAll.get("md5");

        boolean b = checkToken(id,type,expireTime,md5);
        System.out.println(b);

    }

    /**
     * 转成 token
     *
     * @param id
     * @param type 用户类型
     * @return
     */
    public static String toToken(int id, String type) {

        long time = System.currentTimeMillis() + EXPIRE_DATE;


        //todo 生成json 字符串
//        JSON json = CreateJson.CreateJson(username, type, time);

        //todo 将json 转成 md5
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(id);
        stringBuilder.append(type);
        stringBuilder.append(time);

        String sstringBuilder1 = stringBuilder.toString();

        String md5 = md5(sstringBuilder1);
        //todo 将 字符串+ md5 生成 token


        Token token = new Token(id, type, time, md5);

        String tokenString = CreateJson(token);
        log.info("tokenString:{}", tokenString);
        String base64 = Base64.getBase64(tokenString);

//        String token = CreateJson(username, type, time) + s;

        return base64;
    }

//    /**
//     * 将token 转成 String 取出 用户id 用户类型 时间
//     *
//     * @param token token字符串
//     * @return 返回一个map key 0 是用户
//     */
//    public static Map<Integer,String> tokenToString(String token) {
//        String[] split = token.split(",");
//        Map<Integer,String> map = new HashMap<>();
//
//        //获取除了md5码的所有信息
//        for (int i = 0; i < split.length; i++) {
//            map.put(i,split[i]);
//        }
//        return map;
//    }

    /**
     * 验证token 的完整性
     *
     * @return 是否完整
     */
    public static boolean checkToken(int id, String type, long expireTime, String md5) {
        JSONObject jsonObject = null;
        try {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(id);
            stringBuilder.append(type);
            stringBuilder.append(expireTime);

            String md51 = md5(stringBuilder.toString());

            if (md5.equals(md51)) {
                return true;
            }
        } catch (Exception e) {
            log.error("错误信息:{}", "token错误");

        }

        return false;
    }

    /**
     * 获取token的Time
     *
     * @return
     */
    public static Map<String, Object> getTokenAll(String token) {
        JSONObject jsonObject = null;
        Map<String, Object> map = new HashMap<>();
        try {
            jsonObject = JSONObject.parseObject(token);

            int id = jsonObject.getInteger("id");
            String type = jsonObject.getString("type");
            long expireTime = jsonObject.getLong("expireTime");
            String md5 = jsonObject.getString("md5");

            map.put("id", id);
            map.put("type", type);
            map.put("expireTime", expireTime);
            map.put("md5", md5);

        } catch (Exception e) {
            log.error("错误信息:{}", "Token无法转成id,type,time,md5");
        }
        return map;
    }


    /**
     * 将过期时间和当前时间比较  判断token 是否有效
     * 有效 返回true
     */
    public static boolean compareTime(long time) {
        long l = System.currentTimeMillis();
        if (l < time) {
            return true;
        }
        return false;
    }


    /**
     * 生成 md5 码
     *
     * @param data
     * @return
     */

    public static String md5(String data) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            return Hex.encodeHexString(md.digest(data.getBytes(StandardCharsets.UTF_8)));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }


    /**
     * 转换成Json 格式
     *
     * @param token
     * @return JsonString
     */

    public static String CreateJson(Token token) {
        return JSON.toJSONString(token);
    }
}
